<?php
// +----------------------------------------------------------------------
// | snake
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2022 http://baiyf.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: NickBai <1902822973@qq.com>
// +----------------------------------------------------------------------
namespace app\common\model;

use think\Db;
use think\Model;

class BaseModel extends Model
{
    public $softDel = 'delete_time'; //时间类型的软删除
    public $createTime = 'create_time';
    public $updateTime = 'update_time';

    public $projectIdName = 'project_id'; // 多项目 区分 字段

    public $controllerText = ''; // 表中文名称
    public $tableName = '';  //表名，不带前缀，为空的话自动使用本类名称

    /**
     * 备注列的别名
     * @var string
     */
    protected $commentFieldName = '备注';

    /**
     * 列
     * @var array
     */
    private $fields = [
        'list' => [],
        'add' => [],
        'edit' => [],
        'view' => [],
    ];

    /**
     * 附加的 列
     * @var array
     */
    private $addonsFields = [
        'list' => [],
        'add' => [],
        'edit' => [],
        'view' => [],
    ];

    /**
     * 搜索的列
     * @var array
     */
    private $searchFields = [];
    /**
     * 附加的 搜索的列
     * @var array
     */
    protected $addonsSearchFields = [];
    /**
     * 操作按钮
     * [
     *  'text' => '按钮文本'
     *  'type' => '按钮类型'  btn confirm-rst-url-btn
     *  'href' => '链接'
     *  'var' => '变量'    列表中的字段
     *  'tip' => '提醒'    列表中的字段
     * ]
     * @var array
     */
    private $operationBtns = [];

    /**
     *  初始化模型
     * @access protected
     * @return void
     */
    protected function initialize()
    {
        parent::initialize();
        // 初始化各种列
        $this->parseCommentAll();
    }

    /**
     * 解析 全部 备注里面的信息
     * @param $comment
     */
    private function parseCommentAll(){
        $tableName = $this->getTable();
        $cacheKey = $tableName . '_fields_searchFields';
        $data = cache($cacheKey);
        if(empty($data)){
            $fields = $this->getTableFieldsComment();
            foreach ($fields as $field){
                $this->parseComment($field[$this->commentFieldName]);
            }
            cache($cacheKey,[
                'fields' => $this->fields,
                'searchFields' => $this->searchFields,
            ],null,'system');
        }
        else{
            $this->fields = $data['fields'];
            $this->searchFields = $data['searchFields'];
        }
        $cacheKey = $tableName . '_addonsFields';
        $data = cache($cacheKey);
        if(empty($data)) {
            //解析表备注
            $comment = $this->getTableComment();
            if (!empty($comment)) {
                $comment = json_decode($comment, 256);
                if (!empty($comment)) {
                    foreach ($comment['additionalFields'] as $key => $field) {
                        foreach ($field as $item) {
                            $this->setAddonsFields($key, $item);
                        }
                    }

                    cache($cacheKey,[
                        'addonsFields' => $this->addonsFields,
                    ],null,'system');
                }
            }
        }
        else{
            $this->addonsFields = $data['addonsFields'];
        }
    }
    /**
     * 解析 单条 备注里面的信息
     * @param $comment
     */
    private function parseComment($comment){
        $json = json_decode($comment,256);
        // 解析失败，跳过
        if(empty($json)){
            return;
        }
        if (true == $json['isSearch']) {
            $tmp = [
                'key' => $json['name'],
                'text' => $json['search']['text'],
                'op' => $json['search']['op'],
                'type' => $json['type'],
            ];
            if (!empty($json['type_value_custom'])) {
                $tmp['type_value_custom'] = $json['type_value_custom'];
            }
            if (!empty($json['type_value'])) {
                $tmp['type_value'] = $json['type_value'];
            }

            // 排序
            if (!empty($json['sort'])) {
                $tmp['sort'] = $json['sort'];
            } else {
                $tmp['sort'] = 0;
            }

            if (!empty($json['explain'])) {
                $tmp['explain'] = $json['explain'];
            } else {
                $tmp['explain'] = '';
            }

            if (!empty($json['search']['is_tree'])) {
                $tmp['is_tree'] = $json['search']['is_tree'];
            }
            else{
                $tmp['is_tree'] = false;
            }
            if (!empty($json['search']['tree_parent_id_name'])) {
                $tmp['tree_parent_id_name'] = $json['search']['tree_parent_id_name'];
            }
            else{
                $tmp['tree_parent_id_name'] = '';
            }

            $this->searchFields[$json['name']] = $tmp;
        }
        foreach ($json['show'] as $key => $show){
            if(false == $show['checked']){
                continue;
            }
            $this->fields[$key][$json['name']] = [
                'name' => $json['name'],
                'text' => $json['disc'],
                'type' => $json['type'],
            ];
            // 排序
            if(!empty($json['sort'])){
                $this->fields[$key][$json['name']]['sort'] = $json['sort'];
            }
            else{
                $this->fields[$key][$json['name']]['sort'] = 999;
            }
            if (!empty($json['explain'])) {
                $this->fields[$key][$json['name']]['explain'] = $json['explain'];
            } else {
                $this->fields[$key][$json['name']]['explain'] = '';
            }
            if(!empty($json['type_value_custom'])){
                $this->fields[$key][$json['name']]['type_value_custom'] = $json['type_value_custom'];

                // 把树的相关信息 放到顶层 2018.03.26
                if(!empty($json['type_value_custom']['is_tree'])){
                    $this->fields[$key][$json['name']]['is_tree'] = $json['type_value_custom']['is_tree'];
                }
                if(!empty($json['type_value_custom']['tree_parent_id_name'])){
                    $this->fields[$key][$json['name']]['tree_parent_id_name'] = $json['type_value_custom']['tree_parent_id_name'];
                }
            }
            if(!empty($json['type_value'])){
                $this->fields[$key][$json['name']]['type_value'] = $json['type_value'];
            }
            //验证不为空，当显示的时候才验证
            if(!empty($json['validate'])){
                $vs = [];
                foreach ($json['validate'] as $vkey => $validate){
                    if(is_bool($validate)){
                        if(true === $validate){
                            $vs[] = $vkey;
                        }
                    }
                    else{
                        $vs[] = $vkey.':'.$validate;
                    }
                }
                $this->fields[$key][$json['name']]['validate'] = join('|',$vs);
            }
        }
    }
    /**
     * 获取搜索的列
     * @return mixed
     */
    public function getSearchFields(){
        // 先排序
        $arr = array_merge($this->searchFields,$this->addonsSearchFields);
        $key_arrays = [];
        foreach($arr as $val){
            $key_arrays[] = $val['sort'];
        }
        array_multisort(array_column($arr,'sort'),SORT_ASC,SORT_NUMERIC,$arr);
        return $arr;
    }
    /**
     * 获取显示的列
     * @return mixed
     */
    public function getListFields(){
        $type = 'list';
        $arr = array_merge($this->fields[$type],$this->addonsFields[$type]);
        array_multisort(array_column($arr,'sort'),SORT_ASC,$arr);
        return $arr;
    }
    /**
     * 获取添加的列
     * @return mixed
     */
    public function getAddFields(){
        $type = 'add';
        $arr = array_merge($this->fields[$type],$this->addonsFields[$type]);
        array_multisort(array_column($arr,'sort'),SORT_ASC,$arr);
        return $arr;
    }
    /**
     * 获取编辑的列
     * @return mixed
     */
    public function getEditFields(){
        $type = 'edit';
        $arr = array_merge($this->fields[$type],$this->addonsFields[$type]);
        array_multisort(array_column($arr,'sort'),SORT_ASC,$arr);
        return $arr;
    }
    /**
     * 获取查看的列
     * @return mixed
     */
    public function getViewFields(){
        $type = 'view';
        $arr = array_merge($this->fields[$type],$this->addonsFields[$type]);
        array_multisort(array_column($arr,'sort'),SORT_ASC,$arr);
        return $arr;
    }

    /**
     * 获取 操作按钮
     * @return mixed
     */
    public function getOperationBtns(){
        return $this->operationBtns;
    }

    /**
     * 设置 操作按钮
     * @return mixed
     */
    public function setOperationBtns($btn){
        $this->operationBtns[] = $btn;
    }

    /**
     * 获取表中列的全部信息，包括备注
     * @return mixed
     */
    public function getTableFieldsComment(){
        $tableName = $this->getTable();
        $cacheKey = 'getTableFieldsComment_' . $tableName;
        $data = cache($cacheKey);
        if(empty($data)){
            $sql = "SELECT 
                    column_name AS '列名',  
                    data_type   AS '数据类型',   
                    character_maximum_length  AS '字符长度',   
                    numeric_precision AS '数字长度',       
                    numeric_scale AS '小数位数',   
                    is_nullable AS '是否允许非空',   
                    CASE   
                        WHEN extra = 'auto_increment' THEN 1   
                        ELSE 0   
                    END AS '是否自增',   
                    column_default  AS  '默认值',   
                    column_comment  AS  '$this->commentFieldName' 
                    FROM   
                    Information_schema.columns   
                WHERE   
                    table_Name='$tableName'; ";
            $data = Db::query($sql);
            cache($cacheKey,$data,null,'system');
        }

        return $data;
    }

    /**
     * 获取表中备注
     * @return mixed
     */
    public function getTableComment(){
        $tableName = $this->getTable();
        $cacheKey = 'getTableComment_' . $tableName;
        $data = cache($cacheKey);
        if(empty($data)){
            $sql = "SELECT table_name,table_comment  AS  '$this->commentFieldName' FROM information_schema.tables WHERE table_name='$tableName'; ";
            $data = Db::query($sql);
            cache($cacheKey,$data,null,'system');
        }

        if(!empty($data) && count($data) > 0){
            return $data[0][$this->commentFieldName];
        }
        else{
            return '';
        }
    }

    /**
     * 验证数据
     * @param $data
     * @param string $type 类型 add edit
     */
    public function validateData($data,$type){

    }

    public function setAddonsFields($type,$json){
        $this->addonsFields[$type][$json['name']] = $json;
    }
}